Table 1: Data files and associated biological conditions.
name drug type plate new orig
hom_ctrl_G:A ctrl ctrl G ctrlG G1
hom_ctrl_G:B ctrl ctrl G ctrlG G2
hom_ctrl_G:C ctrl ctrl G ctrlG G3
hom_ctrl_G:D ctrl ctrl G ctrlG G4
hom_mtx_G:A mtx trt G mtx G5
hom_mtx_G:B mtx trt G mtx G6
hom_mtx_G:C mtx trt G mtx G7
hom_mtx_G:D mtx trt G mtx G8
hom_dox_G:A dox trt G dox G9
hom_dox_G:B dox trt G dox G10
hom_dox_G:C dox trt G dox G11
hom_dox_G:D dox trt G dox G12
hom_ctrl_N:A ctrl ctrl N ctrlN N1
hom_ctrl_N:B ctrl ctrl N ctrlN N2
hom_ctrl_N:C ctrl ctrl N ctrlN N3
hom_ma_N:A ma trt N ma N4
hom_ma_N:B ma trt N ma N5
hom_ma_N:C ma trt N ma N6
hom_ndma_N:A ndma trt N ndma N7
hom_ndma_N:B ndma trt N ndma N8
hom_ndma_N:C ndma trt N ndma N9
hom_ndea_N:A ndea trt N ndea N10
hom_ndea_N:B ndea trt N ndea N11
hom_ndea_N:C ndea trt N ndea N12
hom_nmba_N:A nmba trt N nmba N13
hom_nmba_N:B nmba trt N nmba N14
hom_nmba_N:C nmba trt N nmba N15

After loading the data we first have a look at the raw data table itself. The data table contains one row per annotated feature and one column per sequenced sample. Row names of this table are feature IDs (unique identifiers). The table contains raw count values representing the number of reads that map onto the features. For this project, there are 4976 features in the count data table.

Table 2: Partial view of the count data table.
hom_ctrl_G:A hom_ctrl_G:B hom_ctrl_G:C hom_ctrl_G:D hom_mtx_G:A hom_mtx_G:B hom_mtx_G:C hom_mtx_G:D hom_dox_G:A hom_dox_G:B hom_dox_G:C hom_dox_G:D hom_ctrl_N:A hom_ctrl_N:B hom_ctrl_N:C hom_ma_N:A hom_ma_N:B hom_ma_N:C hom_ndma_N:A hom_ndma_N:B hom_ndma_N:C hom_ndea_N:A hom_ndea_N:B hom_ndea_N:C hom_nmba_N:A hom_nmba_N:B hom_nmba_N:C
AAC1 2822 2619 4808 3056 2566 2652 3761 3013 3383 1545 1867 3126 2779 3721 2994 1829 2065 1447 1374 3179 2661 3268 2486 4512 2658 1994 2630
AAC3 0 1 43 0 0 0 0 0 2 1 0 0 0 2 6 0 7 0 8 4 4 9 11 12 5 9 4
AAD14 0 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
AAD3 295 167 558 246 220 189 300 272 446 147 180 482 267 295 286 132 81 80 168 526 309 443 284 392 111 151 300
AAD4 819 963 1450 541 596 743 1069 678 916 475 417 631 905 938 701 716 651 539 407 1289 863 749 825 1277 752 619 691
AAD6 315 550 704 192 878 472 790 415 833 168 330 346 199 254 305 167 299 184 206 380 309 338 264 580 341 261 91

Looking at the summary of the count table provides a basic description of these raw counts (min and max values, median, etc).

Table 3: Summary of the raw counts.
hom_ctrl_G:A hom_ctrl_G:B hom_ctrl_G:C hom_ctrl_G:D hom_mtx_G:A hom_mtx_G:B hom_mtx_G:C hom_mtx_G:D hom_dox_G:A hom_dox_G:B hom_dox_G:C hom_dox_G:D hom_ctrl_N:A hom_ctrl_N:B hom_ctrl_N:C hom_ma_N:A hom_ma_N:B hom_ma_N:C hom_ndma_N:A hom_ndma_N:B hom_ndma_N:C hom_ndea_N:A hom_ndea_N:B hom_ndea_N:C hom_nmba_N:A hom_nmba_N:B hom_nmba_N:C
Min. 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
1st Qu. 185 200 325 169 236 198 288 178 280 127 162 198 150 211 168 119 104 77 95 235 169 175 125 204 164 123 151
Median 438 452 750 423 495 440 626 407 648 296 365 488 380 530 417 346 305 222 222 571 407 465 362 608 389 301 365
Mean 557 564 943 545 604 553 773 524 785 357 441 606 501 691 543 500 447 326 284 747 537 606 488 827 493 388 478
3rd Qu. 793 788 1317 758 832 766 1065 727 1101 496 609 843 704 963 743 709 629 461 390 1032 749 844 686 1162 682 540 661
Max. 7327 7754 13266 7327 8876 7499 10583 7640 30631 13985 17098 21588 7061 9694 8320 7864 6531 5758 3751 10546 7570 11535 9546 15697 6288 5747 6924

Figure 1 shows the total number of mapped and counted reads for each sample. We expect total read counts to be similar within conditions, they may be different across conditions. Total counts sometimes vary widely between replicates. This may happen for several reasons, including:

Figure 1: Number of mapped reads per sample. Colors refer to the biological condition of the sample.

Figure 1: Number of mapped reads per sample. Colors refer to the biological condition of the sample.

Figure 2 shows the proportion of features with no read count in each sample. We expect this proportion to be similar within conditions. Features with null read counts in the 27 samples are left in the data but are not taken into account for the analysis with DESeq2. Here, 0 features (0%) are in this situation (dashed line). Results for those features (fold-change and p-values) are set to NA in the results files.

Figure 2: Proportion of features with null read counts in each sample.

Figure 2: Proportion of features with null read counts in each sample.

Figure 3 shows the distribution of read counts for each sample. For sake of readability, \(\text{log}_2(\text{counts}+1)\) are used instead of raw counts. Again we expect replicates to have similar distributions. In addition, this figure shows if read counts are preferably low, medium or high. This depends on the organisms as well as the biological conditions under consideration.

Figure 3a: Density distribution of read counts.

Figure 3a: Density distribution of read counts.

Figure 3b: Density distribution of raw and normalized counts.

Figure 3b: Density distribution of raw and normalized counts.

It may happen that one or a few features capture a high proportion of reads (up to 20% or more). This phenomenon should not influence the normalization process. The DESeq2 normalization has proved to be robust to this situation [Dillies, 2012]. Anyway, we expect these high count features to be the same across replicates. They are not necessarily the same across conditions. Figure 4 and table 4 illustrate the possible presence of such high count features in the data set. - note: rule of thumb, anything above 0.2 is a likely outlier

Figure 4: Percentage of reads associated with the sequence having the highest count (provided in each box on the graph) for each sample.

Figure 4: Percentage of reads associated with the sequence having the highest count (provided in each box on the graph) for each sample.

Table 4: Percentage of reads associated with the sequences having the highest counts.
hom_ctrl_G:A hom_ctrl_G:B hom_ctrl_G:C hom_ctrl_G:D hom_mtx_G:A hom_mtx_G:B hom_mtx_G:C hom_mtx_G:D hom_dox_G:A hom_dox_G:B hom_dox_G:C hom_dox_G:D hom_ctrl_N:A hom_ctrl_N:B hom_ctrl_N:C hom_ma_N:A hom_ma_N:B hom_ma_N:C hom_ndma_N:A hom_ndma_N:B hom_ndma_N:C hom_ndea_N:A hom_ndea_N:B hom_ndea_N:C hom_nmba_N:A hom_nmba_N:B hom_nmba_N:C
COX5A 0.26 0.28 0.28 0.27 0.26 0.27 0.26 0.29 0.22 0.24 0.23 0.26 0.28 0.28 0.31 0.32 0.29 0.35 0.27 0.27 0.28 0.35 0.36 0.33 0.26 0.30 0.29
YDR417C 0.21 0.22 0.20 0.20 0.22 0.22 0.23 0.21 0.09 0.09 0.11 0.12 0.20 0.21 0.20 0.16 0.16 0.18 0.16 0.15 0.19 0.12 0.11 0.12 0.18 0.18 0.19
KGD1 0.20 0.25 0.23 0.23 0.29 0.23 0.24 0.21 0.22 0.27 0.22 0.23 0.21 0.23 0.23 0.25 0.24 0.24 0.25 0.28 0.26 0.22 0.16 0.17 0.22 0.23 0.22
EMI1|48 0.19 0.17 0.18 0.21 0.29 0.26 0.28 0.24 0.16 0.19 0.17 0.21 0.25 0.25 0.26 0.20 0.22 0.23 0.26 0.23 0.21 0.28 0.29 0.29 0.24 0.23 0.26
RTC6|0018 0.16 0.16 0.16 0.17 0.25 0.21 0.25 0.20 0.23 0.23 0.24 0.22 0.18 0.16 0.18 0.13 0.15 0.17 0.19 0.20 0.18 0.12 0.11 0.09 0.17 0.16 0.18
SSN2 0.17 0.16 0.18 0.16 0.16 0.18 0.17 0.16 0.78 0.79 0.78 0.71 0.15 0.17 0.17 0.31 0.28 0.24 0.21 0.18 0.19 0.38 0.39 0.38 0.18 0.17 0.18
YDR442W 0.06 0.07 0.07 0.06 0.06 0.05 0.06 0.06 0.23 0.20 0.18 0.19 0.06 0.05 0.05 0.07 0.07 0.07 0.05 0.05 0.04 0.09 0.07 0.07 0.07 0.05 0.05

We may wish to assess the similarity between samples across conditions. A pairwise scatter plot is produced (figure 5) to show how replicates and samples from different biological conditions are similar or different (\(\text{log}_2(\text{counts}+1)\) are used instead of raw count values). Moreover, as the Pearson correlation has been shown not to be relevant to measure the similarity between replicates, the SERE statistic has been proposed as a similarity index between RNA-Seq samples [1]. It measures whether the variability between samples is random Poisson variability or higher. Pairwise SERE values are printed in the lower triangle of the pairwise scatter plot. The value of the SERE statistic is:

Figure 5: Pairwise comparison of samples (not produced when more than 30 samples).

Figure 5: Pairwise comparison of samples (not produced when more than 30 samples).

Variability within the experiment: data exploration

The main variability within the experiment is expected to come from biological differences between the samples. This can be checked in two ways. The first one is to perform a hierarchical clustering of the whole sample set. This is performed after a transformation of the count data which can be either a Variance Stabilizing Transformation (VST) or a regularized log transformation (rlog) [2,3].

A VST is a transformation of the data that makes them homoscedastic, meaning that the variance is then independent of the mean. It is performed in two steps: (i) a mean-variance relationship is estimated from the data with the same function that is used to normalize count data and (ii) from this relationship, a transformation of the data is performed in order to get a dataset in which the variance is independent of the mean. The homoscedasticity is a prerequisite for the use of some data analysis methods, such as hierarchical clustering or Principal Component Analysis (PCA). The regularized log transformation is based on a GLM (Generalized Linear Model) on the counts and has the same goal as a VST but is more robust in the case when the size factors vary widely.

Figure 6 shows the dendrogram obtained from log transformed data. An euclidean distance is computed between samples, and the dendrogram is built upon the Ward criterion. We expect this dendrogram to group replicates and separate biological conditions.

Figure 6: Sample clustering based on normalized data.

Figure 6: Sample clustering based on normalized data.

Another way of visualizing the experiment variability is to look at the first principal components of the PCA, as shown on the figure 7. On this figure, the first principal component (PC1) is expected to separate samples from the different biological conditions, meaning that the biological variability is the main source of variance in the data.

Figure 7: First two components of a Principal Component Analysis, with percentages of variance associated with each axis.

Figure 7: First two components of a Principal Component Analysis, with percentages of variance associated with each axis.

Another way of visualizing the experiment variability is to look at the first two dimensions of a multidimensional scaling plot, as shown on figure 7. On this figure, the first dimension is expected to separate samples from the different biological conditions, meaning that the biological variability is the main source of variance in the data.

Figure 7b: Multidimensional scaling plot of the samples.

Figure 7b: Multidimensional scaling plot of the samples.

Differential analysis

Modelisation

DESeq2 aims at fitting one linear model per feature. For this project, the design used is counts ~ drug and the goal is to estimate the models’ coefficients which can be interpreted as \(\log_2(\texttt{FC})\). These coefficients will then be tested to get p-values and adjusted p-values.

Outlier detection

Model outliers are features for which at least one sample seems unrelated to the experimental or study design. For every feature and for every sample, the Cook’s distance [4] reflects how the sample matches the model. A large value of the Cook’s distance indicates an outlier count and p-values are not computed for the corresponding feature.

Dispersions estimation

The DESeq2 model assumes that the count data follow a negative binomial distribution which is a robust alternative to the Poisson law when data are over-dispersed (the variance is higher than the mean). The first step of the statistical procedure is to estimate the dispersion of the data. Its purpose is to determine the shape of the mean-variance relationship. The default is to apply a GLM (Generalized Linear Model) based method (fitType=“parametric”), which can handle complex designs but may not converge in some cases. The alternative is to use fitType=“local” as described in the original paper [2]. The parameter used for this project is fitType=“local”. Then, DESeq2 imposes a Cox Reid-adjusted profile likelihood maximization [5] and uses the maximum a posteriori (MAP) of the dispersion [Wu, 2013].

Figure 8: Diagnostic of the estimation of the size factors.

Figure 8: Diagnostic of the estimation of the size factors.

The figure 9 shows that the scaling factors of DESeq2 and the total count normalization factors may not perform similarly.

Figure 9: Plot of the estimated size factors and the total number of reads per sample.

Figure 9: Plot of the estimated size factors and the total number of reads per sample.

Boxplots are often used as a qualitative measure of the quality of the normalization process, as they show how distributions are globally affected during this process. We expect normalization to stabilize distributions across samples. Figure 10 shows boxplots of raw (left) and normalized (right) data respectively.

Figure 10: Boxplots of raw (left) and normalized (right) read counts.

Figure 10: Boxplots of raw (left) and normalized (right) read counts.

Differential analysis

Modelisation

DESeq2 aims at fitting one linear model per feature. For this project, the design used is counts ~ drug and the goal is to estimate the models’ coefficients which can be interpreted as \(\log_2(\texttt{FC})\). These coefficients will then be tested to get p-values and adjusted p-values.

Outlier detection

Model outliers are features for which at least one sample seems unrelated to the experimental or study design. For every feature and for every sample, the Cook’s distance [4] reflects how the sample matches the model. A large value of the Cook’s distance indicates an outlier count and p-values are not computed for the corresponding feature.

Dispersions estimation

The DESeq2 model assumes that the count data follow a negative binomial distribution which is a robust alternative to the Poisson law when data are over-dispersed (the variance is higher than the mean). The first step of the statistical procedure is to estimate the dispersion of the data. Its purpose is to determine the shape of the mean-variance relationship. The default is to apply a GLM (Generalized Linear Model) based method (fitType=“parametric”), which can handle complex designs but may not converge in some cases. The alternative is to use fitType=“local” as described in the original paper [2]. The parameter used for this project is fitType= local. Then, DESeq2 imposes a Cox Reid-adjusted profile likelihood maximization [5] and uses the maximum (MAP) of the dispersion [Wu, 2013].

Figure 11: Dispersion estimates (left) and diagnostic of log-normality (right).

Figure 11: Dispersion estimates (left) and diagnostic of log-normality (right).

The left panel on figure 11 shows the result of the dispersion estimation step. The x- and y-axes represent the mean count value and the estimated dispersion respectively. Black dots represent empirical dispersion estimates for each feature (from the observed counts). The red dots show the mean-variance relationship function (fitted dispersion value) as estimated by the model. The blue dots are the final estimates from the maximum a posteriori and are used to perform the statistical test. Blue circles (if any) point out dispersion outliers. These are features with a very high empirical variance (computed from observed counts). These high dispersion values fall far from the model estimation. For these features, the statistical test is based on the empirical variance in order to be more conservative than with the MAP dispersion. These features will have low chance to be declared significant. The figure on the right panel allows to check the hypothesis of log-normality of the dispersions.

Statistical test for differential expression

Once the dispersion estimation and the model fitting have been done, DESeq2 can perform the statistical testing. Figure 12 shows the distributions of raw p-values computed by the statistical test for the comparison(s) done. This distribution is expected to be a mixture of a uniform distribution on \([0,1]\) and a peak around 0 corresponding to the differentially expressed features.

Figure 12: Distribution(s) of raw p-values.

Figure 12: Distribution(s) of raw p-values.

Independent filtering

DESeq2 can perform an independent filtering to increase the detection power of differentially expressed features at the same experiment-wide type I error. Since features with very low counts are not likely to see significant differences typically due to high dispersion, it defines a threshold on the mean of the normalized counts irrespective of the biological condition. This procedure is independent because the information about the variables in the design formula is not used [3].

Final results

A p-value adjustment is performed to take into account multiple testing and control the false positive rate to a chosen level \(\alpha\). For this analysis, a BH p-value adjustment was performed [6] and the level of controlled false positive rate was set to 0.05.

Figure 13 are the fitness defects (\(\log_2\) ratios) plotted as a function of mean counts – this is useful for knowing whether significant are coming from unusual low (noisy) counts

Figure 13: Log Ratio vs. mean CPM of each comparison.

Figure 13: Log Ratio vs. mean CPM of each comparison.

Figure 14 shows the volcano plots for the comparisons performed and differentially expressed features are still highlighted in red. A volcano plot represents the log of the adjusted P value as a function of the log ratio of differential expression.

Figure 14: Volcano plot(s) of each comparison. Red dots represent significantly differentially expressed features.

Figure 14: Volcano plot(s) of each comparison. Red dots represent significantly differentially expressed features.

Figure 15: Fitness defect plots.

Full results as well as lists of differentially expressed features are provided in the following text files which can be easily read in a spreadsheet. For each comparison:

  • TestVsRef.complete.txt contains results for all the features;
  • TestVsRef.up.txt contains results for significantly up-regulated features. Features are ordered from the most significant adjusted p-value to the less significant one;
  • TestVsRef.down.txt contains results for significantly down-regulated features. Features are ordered from the most significant adjusted p-value to the less significant one.

These files contain the following columns:

  • Id: unique feature identifier;
  • sampleName: raw counts per sample;
  • norm.sampleName: rounded normalized counts per sample;
  • baseMean: base mean over all samples;
  • ctrl, dox, ma, mtx, ndea, ndma and nmba: means (rounded) of normalized counts of the biological conditions;
  • FoldChange: fold change of expression, calculated as \(2^{\log_2(\text{FC})}\);
  • log2FoldChange: \(\log_2(\text{FC})\) as estimated by the GLM model. It reflects the differential expression between Test and Ref and can be interpreted as \(\log_2(\frac{\text{Test}}{\text{Ref}})\). If this value is:
    • around 0: the feature expression is similar in both conditions;
    • positive: the feature is up-regulated (\(\text{Test} > \text{Ref}\));
    • negative: the feature is down-regulated (\(\text{Test} < \text{Ref}\));
  • pvalue: raw p-value from the statistical test;
  • padj: adjusted p-value on which the cut-off \(\alpha\) is applied;
  • dispGeneEst: dispersion parameter estimated from feature counts (i.e. black dots on figure 11);
  • dispFit: dispersion parameter estimated from the model (i.e. red dots on figure 11);
  • dispMAP: dispersion parameter estimated from the Maximum A Posteriori model;
  • dispersion: final dispersion parameter used to perform the test (i.e. blue dots and circles on figure 11);
  • betaConv: convergence of the coefficients of the model (TRUE or FALSE);
  • maxCooks: maximum Cook’s distance of the feature.

R session information and parameters

The versions of the R software and Bioconductor packages used for this analysis are listed below. It is important to save them if one wants to re-perform the analysis in the same conditions.

Parameter values used for this analysis are:

Bibliography

1. Schulze SK, Kanwar R, Gölzenleuchter M et al. SERE: Single-parameter quality control and sample comparison for rna-seq. BMC Genomics 2012 ; 13: 524.

2. Anders S, Huber W. Differential expression analysis for sequence count data. Genome Biology 2010 ; 11: R106.

3. Love MI, Huber W, Anders S. Moderated estimation of fold change and dispersion for rna-seq data with deseq2. Genome Biology 2014 ; 15: 550.

4. Cook RD. Detection of influential observation in linear regression. Technometrics 1977 ; 19: 15–18.

5. Cox DR, Reid N. Parameter orthogonality and approximate conditional inference. Journal of the Royal Statistical Society. Series B (Methodological) 1987 ; 49: 1–39.

6. Benjamini Y, Hochberg Y. Controlling the false discovery rate: A practical and powerful approach to multiple testing. Journal of the Royal Statistical Society. Series B (Methodological) 1995 ; 57: 289–300.

LS0tCnRpdGxlOiAnYHIgcGFzdGUwKCJTdGF0aXN0aWNhbCByZXBvcnQgb2YgcHJvamVjdCAiLCBwcm9qZWN0TmFtZSwgIjogcGFpcndpc2UgY29tcGFyaXNvbihzKSBvZiBjb25kaXRpb25zIHdpdGggREVTZXEyIilgJwphdXRob3I6ICdgciBhdXRob3JgJwpkYXRlOiAnYHIgU3lzLkRhdGUoKWAnCm91dHB1dDoKICBodG1sX25vdGVib29rOiAKICAgIHRvYzogeWVzCiAgcGRmX2RvY3VtZW50OiAKICAgIHRvYzogVFJVRQogICAga2VlcF90ZXg6IFRSVUUKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiBUUlVFCiAgICB0b2NfZmxvYXQ6IFRSVUUKICAgIG51bWJlcl9zZWN0aW9uczogVFJVRQpiaWJsaW9ncmFwaHk6ICIvaG9tZS9nZ2lhZXZlci9SL2xpYnJhcnkvU0FSVG9vbHMvYmlibGlvZ3JhcGh5LmJpYiIKY3NsOiAiL2hvbWUvZ2dpYWV2ZXIvUi9saWJyYXJ5L1NBUlRvb2xzL21lZGVjaW5lLXNjaWVuY2VzLmNzbCIKZWRpdG9yX29wdGlvbnM6IAogIGNodW5rX291dHB1dF90eXBlOiBjb25zb2xlCi0tLQpgYGB7ciBzZXR1cCwgZWNobyA9IEYsZXZhbCA9IEZ9CiMgbGlicmFyeShrbml0cikKIyBrbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFQpCiMgbGlicmFyeShkcGx5cikKIyAjICMgbGlicmFyeShyZXNoYXBlMikKIyBsaWJyYXJ5KGdncGxvdDIpCiMgbGlicmFyeShzdmEpCiMgbGlicmFyeShERVNlcTIpCmxpYnJhcnkoeHRhYmxlKQojIERlc2NyaXB0aW9uIG9mIHJhdyBkYXRhCgpUaGUgY291bnQgZGF0YSBmaWxlcyBhbmQgYXNzb2NpYXRlZCBiaW9sb2dpY2FsIGNvbmRpdGlvbnMgYXJlIGxpc3RlZCBpbiB0aGUgZm9sbG93aW5nIHRhYmxlLgpgYGAKCgpgYGB7ciAsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImFzaXMifQpwcmludCh4dGFibGUodGFyZ2V0LGNhcHRpb249IlRhYmxlIDE6IERhdGEgZmlsZXMgYW5kIGFzc29jaWF0ZWQgYmlvbG9naWNhbCBjb25kaXRpb25zLiIpLCB0eXBlPSJodG1sIiwgaW5jbHVkZS5yb3duYW1lcz1GQUxTRSwgaHRtbC50YWJsZS5hdHRyaWJ1dGVzID0gImFsaWduPSdjZW50ZXInIikKYGBgCgpBZnRlciBsb2FkaW5nIHRoZSBkYXRhIHdlIGZpcnN0IGhhdmUgYSBsb29rIGF0IHRoZSByYXcgZGF0YSB0YWJsZSBpdHNlbGYuIFRoZSBkYXRhIHRhYmxlIGNvbnRhaW5zIG9uZSByb3cgcGVyIGFubm90YXRlZCBmZWF0dXJlIGFuZCBvbmUgY29sdW1uIHBlciBzZXF1ZW5jZWQgc2FtcGxlLiBSb3cgbmFtZXMgb2YgdGhpcyB0YWJsZSBhcmUgZmVhdHVyZSBJRHMgKHVuaXF1ZSBpZGVudGlmaWVycykuIFRoZSB0YWJsZSBjb250YWlucyByYXcgY291bnQgdmFsdWVzIHJlcHJlc2VudGluZyB0aGUgbnVtYmVyIG9mIHJlYWRzIHRoYXQgbWFwIG9udG8gdGhlIGZlYXR1cmVzLiBGb3IgdGhpcyBwcm9qZWN0LCB0aGVyZSBhcmUgYHIgbnJvdyhjb3VudHMpYCBmZWF0dXJlcyBpbiB0aGUgY291bnQgZGF0YSB0YWJsZS4KCmBgYHtyICwgZWNobz1GQUxTRSwgcmVzdWx0cz0iYXNpcyJ9CnByaW50KHh0YWJsZShoZWFkKGNvdW50cyksY2FwdGlvbj0iVGFibGUgMjogUGFydGlhbCB2aWV3IG9mIHRoZSBjb3VudCBkYXRhIHRhYmxlLiIsZGlnaXRzPTApLCB0eXBlPSJodG1sIiwgaHRtbC50YWJsZS5hdHRyaWJ1dGVzID0gImFsaWduPSdjZW50ZXInIikKYGBgCgpMb29raW5nIGF0IHRoZSBzdW1tYXJ5IG9mIHRoZSBjb3VudCB0YWJsZSBwcm92aWRlcyBhIGJhc2ljIGRlc2NyaXB0aW9uIG9mIHRoZXNlIHJhdyBjb3VudHMgKG1pbiBhbmQgbWF4IHZhbHVlcywgbWVkaWFuLCBldGMpLgoKYGBge3IgLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJhc2lzIn0KZnVuX3N1bW1hcnk9ZnVuY3Rpb24oeCl7CiAgb3V0PWMocXVhbnRpbGUoeCxjKDAsMC4yNSwwLjUpLHR5cGU9MSksbWVhbih4KSxxdWFudGlsZSh4LGMoMC43NSwxKSx0eXBlPTEpKQogIG5hbWVzKG91dCk9YygiTWluLiIsIjFzdCBRdS4iLCJNZWRpYW4iLCJNZWFuIiwiM3JkIFF1LiIsIk1heC4iKQogIHJldHVybihyb3VuZChvdXQsMCkpCn0KcHJpbnQoeHRhYmxlKGFwcGx5KGNvdW50cywyLGZ1bl9zdW1tYXJ5KSxjYXB0aW9uPSJUYWJsZSAzOiBTdW1tYXJ5IG9mIHRoZSByYXcgY291bnRzLiIsZGlnaXRzPTApLCB0eXBlPSJodG1sIiwgaHRtbC50YWJsZS5hdHRyaWJ1dGVzID0gImFsaWduPSdjZW50ZXInIikKbmJOdWxsIDwtIG5yb3coY291bnRzKSAtIG5yb3cocmVtb3ZlTnVsbChjb3VudHMpKSAjIG5lZWRlZCBpbiBvbmUgb2YgdGhlIG5leHQgcGFyYWdyYXBocwpgYGAKCkZpZ3VyZSAxIHNob3dzIHRoZSB0b3RhbCBudW1iZXIgb2YgbWFwcGVkIGFuZCBjb3VudGVkIHJlYWRzIGZvciBlYWNoIHNhbXBsZS4gV2UgZXhwZWN0IHRvdGFsIHJlYWQgY291bnRzIHRvIGJlIHNpbWlsYXIgd2l0aGluIGNvbmRpdGlvbnMsIHRoZXkgbWF5IGJlIGRpZmZlcmVudCBhY3Jvc3MgY29uZGl0aW9ucy4gVG90YWwgY291bnRzIHNvbWV0aW1lcyB2YXJ5IHdpZGVseSBiZXR3ZWVuIHJlcGxpY2F0ZXMuIFRoaXMgbWF5IGhhcHBlbiBmb3Igc2V2ZXJhbCByZWFzb25zLCBpbmNsdWRpbmc6CgotIGRpZmZlcmVudCByUk5BIGNvbnRhbWluYXRpb24gbGV2ZWxzIGJldHdlZW4gc2FtcGxlcyAoZXZlbiBiZXR3ZWVuIGJpb2xvZ2ljYWwgcmVwbGljYXRlcyk7Ci0gc2xpZ2h0IGRpZmZlcmVuY2VzIGJldHdlZW4gbGlicmFyeSBjb25jZW50cmF0aW9ucywgc2luY2UgdGhleSBtYXkgYmUgZGlmZmljdWx0IHRvIG1lYXN1cmUgd2l0aCBoaWdoIHByZWNpc2lvbi4KCjxjZW50ZXI+CiFbRmlndXJlIDE6IE51bWJlciBvZiBtYXBwZWQgcmVhZHMgcGVyIHNhbXBsZS4gQ29sb3JzIHJlZmVyIHRvIHRoZSBiaW9sb2dpY2FsIGNvbmRpdGlvbiBvZiB0aGUgc2FtcGxlLl0oZmlndXJlcy9iYXJwbG90VG90YWwucG5nKXt3aWR0aD02MDB9Cgo8L2NlbnRlcj4KCkZpZ3VyZSAyIHNob3dzIHRoZSBwcm9wb3J0aW9uIG9mIGZlYXR1cmVzIHdpdGggbm8gcmVhZCBjb3VudCBpbiBlYWNoIHNhbXBsZS4gV2UgZXhwZWN0IHRoaXMgcHJvcG9ydGlvbiB0byBiZSBzaW1pbGFyIHdpdGhpbiBjb25kaXRpb25zLiBGZWF0dXJlcyB3aXRoIG51bGwgcmVhZCBjb3VudHMgaW4gdGhlIGByIG5jb2woY291bnRzKWAgc2FtcGxlcyBhcmUgbGVmdCBpbiB0aGUgZGF0YSBidXQgYXJlIG5vdCB0YWtlbiBpbnRvIGFjY291bnQgZm9yIHRoZSBhbmFseXNpcyB3aXRoIERFU2VxMi4gSGVyZSwgYHIgbmJOdWxsYCBmZWF0dXJlcyAoYHIgcm91bmQoMTAwKm5iTnVsbC9ucm93KGNvdW50cyksMilgJSkgYXJlIGluIHRoaXMgc2l0dWF0aW9uIChkYXNoZWQgbGluZSkuIFJlc3VsdHMgZm9yIHRob3NlIGZlYXR1cmVzIChmb2xkLWNoYW5nZSBhbmQgcC12YWx1ZXMpIGFyZSBzZXQgdG8gTkEgaW4gdGhlIHJlc3VsdHMgZmlsZXMuCgo8Y2VudGVyPgohW0ZpZ3VyZSAyOiBQcm9wb3J0aW9uIG9mIGZlYXR1cmVzIHdpdGggbnVsbCByZWFkIGNvdW50cyBpbiBlYWNoIHNhbXBsZS5dKGZpZ3VyZXMvYmFycGxvdE51bGwucG5nKXt3aWR0aD02MDB9Cgo8L2NlbnRlcj4KCkZpZ3VyZSAzIHNob3dzIHRoZSBkaXN0cmlidXRpb24gb2YgcmVhZCBjb3VudHMgZm9yIGVhY2ggc2FtcGxlLiBGb3Igc2FrZSBvZiByZWFkYWJpbGl0eSwgJFx0ZXh0e2xvZ31fMihcdGV4dHtjb3VudHN9KzEpJCBhcmUgdXNlZCBpbnN0ZWFkIG9mIHJhdyBjb3VudHMuIEFnYWluIHdlIGV4cGVjdCByZXBsaWNhdGVzIHRvIGhhdmUgc2ltaWxhciBkaXN0cmlidXRpb25zLiBJbiBhZGRpdGlvbiwgdGhpcyBmaWd1cmUgc2hvd3MgaWYgcmVhZCBjb3VudHMgYXJlIHByZWZlcmFibHkgbG93LCBtZWRpdW0gb3IgaGlnaC4gVGhpcyBkZXBlbmRzIG9uIHRoZSBvcmdhbmlzbXMgYXMgd2VsbCBhcyB0aGUgYmlvbG9naWNhbCBjb25kaXRpb25zIHVuZGVyIGNvbnNpZGVyYXRpb24uCgoKPGNlbnRlcj4KIVtGaWd1cmUgM2E6IERlbnNpdHkgZGlzdHJpYnV0aW9uIG9mIHJlYWQgY291bnRzLl0oZmlndXJlcy9kZW5zcGxvdC5wbmcpe3dpZHRoPTYwMH0KCjwvY2VudGVyPgoKPGNlbnRlcj4KIVtGaWd1cmUgM2I6IERlbnNpdHkgZGlzdHJpYnV0aW9uIG9mIHJhdyBhbmQgbm9ybWFsaXplZCBjb3VudHMuXShmaWd1cmVzL2RlbnNfbm9ybS5wbmcpe3dpZHRoPTYwMH0KCjwvY2VudGVyPgoKCgpJdCBtYXkgaGFwcGVuIHRoYXQgb25lIG9yIGEgZmV3IGZlYXR1cmVzIGNhcHR1cmUgYSBoaWdoIHByb3BvcnRpb24gb2YgcmVhZHMgKHVwIHRvIDIwJSBvciBtb3JlKS4gVGhpcyBwaGVub21lbm9uIHNob3VsZCBub3QgaW5mbHVlbmNlIHRoZSBub3JtYWxpemF0aW9uIHByb2Nlc3MuIFRoZSBERVNlcTIgbm9ybWFsaXphdGlvbiBoYXMgcHJvdmVkIHRvIGJlIHJvYnVzdCB0byB0aGlzIHNpdHVhdGlvbiBbRGlsbGllcywgMjAxMl0uIEFueXdheSwgd2UgZXhwZWN0IHRoZXNlIGhpZ2ggY291bnQgZmVhdHVyZXMgdG8gYmUgdGhlIHNhbWUgYWNyb3NzIHJlcGxpY2F0ZXMuIFRoZXkgYXJlIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBhY3Jvc3MgY29uZGl0aW9ucy4gRmlndXJlIDQgYW5kIHRhYmxlIDQgaWxsdXN0cmF0ZSB0aGUgcG9zc2libGUgcHJlc2VuY2Ugb2Ygc3VjaCBoaWdoIGNvdW50IGZlYXR1cmVzIGluIHRoZSBkYXRhIHNldC4KLSBub3RlOiBydWxlIG9mIHRodW1iLCBhbnl0aGluZyBhYm92ZSAwLjIgaXMgYSBsaWtlbHkgb3V0bGllcgoKCjxjZW50ZXI+CiFbRmlndXJlIDQ6IFBlcmNlbnRhZ2Ugb2YgcmVhZHMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzZXF1ZW5jZSBoYXZpbmcgdGhlIGhpZ2hlc3QgY291bnQgKHByb3ZpZGVkIGluIGVhY2ggYm94IG9uIHRoZSBncmFwaCkgZm9yIGVhY2ggc2FtcGxlLl0oZmlndXJlcy9tYWpTZXEucG5nKXt3aWR0aD02MDB9Cgo8L2NlbnRlcj4KCgpgYGB7ciAsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImFzaXMifQpwcmludCh4dGFibGUoYXMubWF0cml4KG1halNlcXVlbmNlcyksY2FwdGlvbj0iVGFibGUgNDogUGVyY2VudGFnZSBvZiByZWFkcyBhc3NvY2lhdGVkIHdpdGggdGhlIHNlcXVlbmNlcyBoYXZpbmcgdGhlIGhpZ2hlc3QgY291bnRzLiIpLCB0eXBlPSJodG1sIiwgaHRtbC50YWJsZS5hdHRyaWJ1dGVzID0gImFsaWduPSdjZW50ZXInIikKYGBgCgpXZSBtYXkgd2lzaCB0byBhc3Nlc3MgdGhlIHNpbWlsYXJpdHkgYmV0d2VlbiBzYW1wbGVzIGFjcm9zcyBjb25kaXRpb25zLiBBIHBhaXJ3aXNlIHNjYXR0ZXIgcGxvdCBpcyBwcm9kdWNlZCAoZmlndXJlIDUpIHRvIHNob3cgaG93IHJlcGxpY2F0ZXMgYW5kIHNhbXBsZXMgZnJvbSBkaWZmZXJlbnQgYmlvbG9naWNhbCBjb25kaXRpb25zIGFyZSBzaW1pbGFyIG9yIGRpZmZlcmVudCAoJFx0ZXh0e2xvZ31fMihcdGV4dHtjb3VudHN9KzEpJCBhcmUgdXNlZCBpbnN0ZWFkIG9mIHJhdyBjb3VudCB2YWx1ZXMpLiBNb3Jlb3ZlciwgYXMgdGhlIFBlYXJzb24gY29ycmVsYXRpb24gaGFzIGJlZW4gc2hvd24gbm90IHRvIGJlIHJlbGV2YW50IHRvIG1lYXN1cmUgdGhlIHNpbWlsYXJpdHkgYmV0d2VlbiByZXBsaWNhdGVzLCB0aGUgU0VSRSBzdGF0aXN0aWMgaGFzIGJlZW4gcHJvcG9zZWQgYXMgYSBzaW1pbGFyaXR5IGluZGV4IGJldHdlZW4gUk5BLVNlcSBzYW1wbGVzIFtAU2NodWx6ZTIwMTJdLiBJdCBtZWFzdXJlcyB3aGV0aGVyIHRoZSB2YXJpYWJpbGl0eSBiZXR3ZWVuIHNhbXBsZXMgaXMgcmFuZG9tIFBvaXNzb24gdmFyaWFiaWxpdHkgb3IgaGlnaGVyLiBQYWlyd2lzZSBTRVJFIHZhbHVlcyBhcmUgcHJpbnRlZCBpbiB0aGUgbG93ZXIgdHJpYW5nbGUgb2YgdGhlIHBhaXJ3aXNlIHNjYXR0ZXIgcGxvdC4gVGhlIHZhbHVlIG9mIHRoZSBTRVJFIHN0YXRpc3RpYyBpczoKCi0gMCB3aGVuIHNhbXBsZXMgYXJlIGlkZW50aWNhbCAobm8gdmFyaWFiaWxpdHkgYXQgYWxsOiB0aGlzIG1heSBoYXBwZW4gaW4gdGhlIGNhc2Ugb2YgYSBzYW1wbGUgZHVwbGljYXRpb24pOwoKLSAxIGZvciB0ZWNobmljYWwgcmVwbGljYXRlcyAodGVjaG5pY2FsIHZhcmlhYmlsaXR5IGZvbGxvd3MgYSBQb2lzc29uIGRpc3RyaWJ1dGlvbik7CgotIGdyZWF0ZXIgdGhhbiAxIGZvciBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMgYW5kIHNhbXBsZXMgZnJvbSBkaWZmZXJlbnQgYmlvbG9naWNhbCBjb25kaXRpb25zIChiaW9sb2dpY2FsIHZhcmlhYmlsaXR5IGlzIGhpZ2hlciB0aGFuIHRlY2huaWNhbCBvbmUsIGRhdGEgYXJlIG92ZXItZGlzcGVyc2VkIHdpdGggcmVzcGVjdCB0byBQb2lzc29uKS4gVGhlIGhpZ2hlciB0aGUgU0VSRSB2YWx1ZSwgdGhlIGxvd2VyIHRoZSBzaW1pbGFyaXR5LiBJdCBpcyBleHBlY3RlZCB0byBiZSBsb3dlciBiZXR3ZWVuIGJpb2xvZ2ljYWwgcmVwbGljYXRlcyB0aGFuIGJldHdlZW4gc2FtcGxlcyBvZiBkaWZmZXJlbnQgYmlvbG9naWNhbCBjb25kaXRpb25zLiBIZW5jZSwgdGhlIFNFUkUgc3RhdGlzdGljIGNhbiBiZSB1c2VkIHRvIGRldGVjdCBpbnZlcnNpb25zIGJldHdlZW4gc2FtcGxlcy4KCgo8Y2VudGVyPgohW0ZpZ3VyZSA1OiBQYWlyd2lzZSBjb21wYXJpc29uIG9mIHNhbXBsZXMgKG5vdCBwcm9kdWNlZCB3aGVuIG1vcmUgdGhhbiAzMCBzYW1wbGVzKS5dKGZpZ3VyZXMvcGFpcndpc2VTY2F0dGVyLnBuZykKCjwvY2VudGVyPgoKIyBWYXJpYWJpbGl0eSB3aXRoaW4gdGhlIGV4cGVyaW1lbnQ6IGRhdGEgZXhwbG9yYXRpb24KClRoZSBtYWluIHZhcmlhYmlsaXR5IHdpdGhpbiB0aGUgZXhwZXJpbWVudCBpcyBleHBlY3RlZCB0byBjb21lIGZyb20gYmlvbG9naWNhbCBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBzYW1wbGVzLiBUaGlzIGNhbiBiZSBjaGVja2VkIGluIHR3byB3YXlzLiBUaGUgZmlyc3Qgb25lIGlzIHRvIHBlcmZvcm0gYSBoaWVyYXJjaGljYWwgY2x1c3RlcmluZyBvZiB0aGUgd2hvbGUgc2FtcGxlIHNldC4gVGhpcyBpcyBwZXJmb3JtZWQgYWZ0ZXIgYSB0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgY291bnQgZGF0YSB3aGljaCBjYW4gYmUgZWl0aGVyIGEgVmFyaWFuY2UgU3RhYmlsaXppbmcgVHJhbnNmb3JtYXRpb24gKFZTVCkgb3IgYSByZWd1bGFyaXplZCBsb2cgdHJhbnNmb3JtYXRpb24gKHJsb2cpIFtAQW5kZXJzMjAxMDsgQExvdmUyMDE0XS4KCkEgVlNUIGlzIGEgdHJhbnNmb3JtYXRpb24gb2YgdGhlIGRhdGEgdGhhdCBtYWtlcyB0aGVtIGhvbW9zY2VkYXN0aWMsIG1lYW5pbmcgdGhhdCB0aGUgdmFyaWFuY2UgaXMgdGhlbiBpbmRlcGVuZGVudCBvZiB0aGUgbWVhbi4gSXQgaXMgcGVyZm9ybWVkIGluIHR3byBzdGVwczogKGkpIGEgbWVhbi12YXJpYW5jZSByZWxhdGlvbnNoaXAgaXMgZXN0aW1hdGVkIGZyb20gdGhlIGRhdGEgd2l0aCB0aGUgc2FtZSBmdW5jdGlvbiB0aGF0IGlzIHVzZWQgdG8gbm9ybWFsaXplIGNvdW50IGRhdGEgYW5kIChpaSkgZnJvbSB0aGlzIHJlbGF0aW9uc2hpcCwgYSB0cmFuc2Zvcm1hdGlvbiBvZiB0aGUgZGF0YSBpcyBwZXJmb3JtZWQgaW4gb3JkZXIgdG8gZ2V0IGEgZGF0YXNldCBpbiB3aGljaCB0aGUgdmFyaWFuY2UgaXMgaW5kZXBlbmRlbnQgb2YgdGhlIG1lYW4uIFRoZSBob21vc2NlZGFzdGljaXR5IGlzIGEgcHJlcmVxdWlzaXRlIGZvciB0aGUgdXNlIG9mIHNvbWUgZGF0YSBhbmFseXNpcyBtZXRob2RzLCBzdWNoIGFzIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIG9yIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMgKFBDQSkuIFRoZSByZWd1bGFyaXplZCBsb2cgdHJhbnNmb3JtYXRpb24gaXMgYmFzZWQgb24gYSBHTE0gKEdlbmVyYWxpemVkIExpbmVhciBNb2RlbCkgb24gdGhlIGNvdW50cyBhbmQgaGFzIHRoZSBzYW1lIGdvYWwgYXMgYSBWU1QgYnV0IGlzIG1vcmUgcm9idXN0IGluIHRoZSBjYXNlIHdoZW4gdGhlIHNpemUgZmFjdG9ycyB2YXJ5IHdpZGVseS4KCkZpZ3VyZSA2IHNob3dzIHRoZSBkZW5kcm9ncmFtIG9idGFpbmVkIGZyb20gbG9nIHRyYW5zZm9ybWVkIGRhdGEuIEFuIGV1Y2xpZGVhbiBkaXN0YW5jZSBpcyBjb21wdXRlZCBiZXR3ZWVuIHNhbXBsZXMsIGFuZCB0aGUgZGVuZHJvZ3JhbSBpcyBidWlsdCB1cG9uIHRoZSBXYXJkIGNyaXRlcmlvbi4gV2UgZXhwZWN0IHRoaXMgZGVuZHJvZ3JhbSB0byBncm91cCByZXBsaWNhdGVzIGFuZCBzZXBhcmF0ZSBiaW9sb2dpY2FsIGNvbmRpdGlvbnMuCgo8Y2VudGVyPgohW0ZpZ3VyZSA2OiBTYW1wbGUgY2x1c3RlcmluZyBiYXNlZCBvbiBub3JtYWxpemVkIGRhdGEuXShmaWd1cmVzL2NsdXN0ZXIucG5nKXt3aWR0aD02MDB9Cgo8L2NlbnRlcj4KCkFub3RoZXIgd2F5IG9mIHZpc3VhbGl6aW5nIHRoZSBleHBlcmltZW50IHZhcmlhYmlsaXR5IGlzIHRvIGxvb2sgYXQgdGhlIGZpcnN0IHByaW5jaXBhbCBjb21wb25lbnRzIG9mIHRoZSBQQ0EsIGFzIHNob3duIG9uIHRoZSBmaWd1cmUgNy4gT24gdGhpcyBmaWd1cmUsIHRoZSBmaXJzdCBwcmluY2lwYWwgY29tcG9uZW50IChQQzEpIGlzIGV4cGVjdGVkIHRvIHNlcGFyYXRlIHNhbXBsZXMgZnJvbSB0aGUgZGlmZmVyZW50IGJpb2xvZ2ljYWwgY29uZGl0aW9ucywgbWVhbmluZyB0aGF0IHRoZSBiaW9sb2dpY2FsIHZhcmlhYmlsaXR5IGlzIHRoZSBtYWluIHNvdXJjZSBvZiB2YXJpYW5jZSBpbiB0aGUgZGF0YS4KCgo8Y2VudGVyPgohW0ZpZ3VyZSA3OiBGaXJzdCB0d28gY29tcG9uZW50cyBvZiBhIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMsIHdpdGggcGVyY2VudGFnZXMgb2YgdmFyaWFuY2UgYXNzb2NpYXRlZCB3aXRoIGVhY2ggYXhpcy5dKGZpZ3VyZXMvUENBLnBuZyl7d2lkdGg9MTIwMH0KCjwvY2VudGVyPgoKCkFub3RoZXIgd2F5IG9mIHZpc3VhbGl6aW5nIHRoZSBleHBlcmltZW50IHZhcmlhYmlsaXR5IGlzIHRvIGxvb2sgYXQgdGhlIGZpcnN0IHR3byBkaW1lbnNpb25zIG9mIGEgbXVsdGlkaW1lbnNpb25hbCBzY2FsaW5nIHBsb3QsIGFzIHNob3duIG9uIGZpZ3VyZSA3LiBPbiB0aGlzIGZpZ3VyZSwgdGhlIGZpcnN0IGRpbWVuc2lvbiBpcyBleHBlY3RlZCB0byBzZXBhcmF0ZSBzYW1wbGVzIGZyb20gdGhlIGRpZmZlcmVudCBiaW9sb2dpY2FsIGNvbmRpdGlvbnMsIG1lYW5pbmcgdGhhdCB0aGUgYmlvbG9naWNhbCB2YXJpYWJpbGl0eSBpcyB0aGUgbWFpbiBzb3VyY2Ugb2YgdmFyaWFuY2UgaW4gdGhlIGRhdGEuCgoKPGNlbnRlcj4KIVtGaWd1cmUgN2I6IE11bHRpZGltZW5zaW9uYWwgc2NhbGluZyBwbG90IG9mIHRoZSBzYW1wbGVzLl0oZmlndXJlcy9NRFMucG5nKXt3aWR0aD02MDB9Cgo8L2NlbnRlcj4KCgpgYGB7ciAsIGVjaG89RkFMU0UsIHJlc3VsdHM9ImFzaXMifQppZiAoIWlzLm51bGwoYmF0Y2gpKXsKICBjYXQoIkZvciB0aGUgc3RhdGlzdGljYWwgYW5hbHlzaXMsIHdlIG5lZWQgdG8gdGFrZSBpbnRvIGFjY291bnQgdGhlIGVmZmVjdCBvZiB0aGUgIixiYXRjaCwiIHBhcmFtZXRlci4gU3RhdGlzdGljYWwgbW9kZWxzIGFuZCB0ZXN0cyB3aWxsIHRodXMgYmUgYWRqdXN0ZWQgb24gaXQuXG4iKQp9CmBgYAoKIyBEaWZmZXJlbnRpYWwgYW5hbHlzaXMKCiMjIE1vZGVsaXNhdGlvbgoKREVTZXEyIGFpbXMgYXQgZml0dGluZyBvbmUgbGluZWFyIG1vZGVsIHBlciBmZWF0dXJlLiBGb3IgdGhpcyBwcm9qZWN0LCB0aGUgZGVzaWduIHVzZWQgaXMgCmNvdW50cyBgciBwYXN0ZShhcy5jaGFyYWN0ZXIoZGVzaWduKG91dC5ERVNlcTIkZGRzKSksY29sbGFwc2U9IiAiKWAgYW5kIHRoZSBnb2FsIGlzIHRvIGVzdGltYXRlIHRoZSBtb2RlbHMnIGNvZWZmaWNpZW50cyB3aGljaCBjYW4gYmUgaW50ZXJwcmV0ZWQgYXMgJFxsb2dfMihcdGV4dHR0e0ZDfSkkLiBUaGVzZSBjb2VmZmljaWVudHMgd2lsbCB0aGVuIGJlIHRlc3RlZCB0byBnZXQgcC12YWx1ZXMgYW5kIGFkanVzdGVkIHAtdmFsdWVzLgoKIyMgT3V0bGllciBkZXRlY3Rpb24KCk1vZGVsIG91dGxpZXJzIGFyZSBmZWF0dXJlcyBmb3Igd2hpY2ggYXQgbGVhc3Qgb25lIHNhbXBsZSBzZWVtcyB1bnJlbGF0ZWQgdG8gdGhlIGV4cGVyaW1lbnRhbCBvciBzdHVkeSBkZXNpZ24uIEZvciBldmVyeSBmZWF0dXJlIGFuZCBmb3IgZXZlcnkgc2FtcGxlLCB0aGUgQ29vaydzIGRpc3RhbmNlIFtAY29vazE5NzddIHJlZmxlY3RzIGhvdyB0aGUgc2FtcGxlIG1hdGNoZXMgdGhlIG1vZGVsLiBBIGxhcmdlIHZhbHVlIG9mIHRoZSBDb29rJ3MgZGlzdGFuY2UgaW5kaWNhdGVzIGFuIG91dGxpZXIgY291bnQgYW5kIHAtdmFsdWVzIGFyZSBub3QgY29tcHV0ZWQgZm9yIHRoZSBjb3JyZXNwb25kaW5nIGZlYXR1cmUuIGByIGlmZWxzZSghY29va3NDdXRvZmYsIkZvciB0aGlzIHByb2plY3QsIHRoZSBkZXRlY3Rpb24gb2YgbW9kZWwgb3V0bGllcnMgaGF2ZSBiZWVuIHR1cm5lZCBvZmYgYnkgc2V0dGluZyB0aGUgY3V0LW9mZiB0byB0aGUgaW5maW5pdGUuIiwiIilgCgojIyBEaXNwZXJzaW9ucyBlc3RpbWF0aW9uCgpUaGUgREVTZXEyIG1vZGVsIGFzc3VtZXMgdGhhdCB0aGUgY291bnQgZGF0YSBmb2xsb3cgYSBuZWdhdGl2ZSBiaW5vbWlhbCBkaXN0cmlidXRpb24gd2hpY2ggaXMgYSByb2J1c3QgYWx0ZXJuYXRpdmUgdG8gdGhlIFBvaXNzb24gbGF3IHdoZW4gZGF0YSBhcmUgb3Zlci1kaXNwZXJzZWQgKHRoZSB2YXJpYW5jZSBpcyBoaWdoZXIgdGhhbiB0aGUgbWVhbikuIFRoZSBmaXJzdCBzdGVwIG9mIHRoZSBzdGF0aXN0aWNhbCBwcm9jZWR1cmUgaXMgdG8gZXN0aW1hdGUgdGhlIGRpc3BlcnNpb24gb2YgdGhlIGRhdGEuIEl0cyBwdXJwb3NlIGlzIHRvIGRldGVybWluZSB0aGUgc2hhcGUgb2YgdGhlIG1lYW4tdmFyaWFuY2UgcmVsYXRpb25zaGlwLiBUaGUgZGVmYXVsdCBpcyB0byBhcHBseSBhIEdMTSAoR2VuZXJhbGl6ZWQgTGluZWFyIE1vZGVsKSBiYXNlZCBtZXRob2QgKGZpdFR5cGU9InBhcmFtZXRyaWMiKSwgd2hpY2ggY2FuIGhhbmRsZSBjb21wbGV4IGRlc2lnbnMgYnV0IG1heSBub3QgY29udmVyZ2UgaW4gc29tZSBjYXNlcy4gVGhlIGFsdGVybmF0aXZlIGlzIHRvIHVzZSBmaXRUeXBlPSJsb2NhbCIgYXMgZGVzY3JpYmVkIGluIHRoZSBvcmlnaW5hbCBwYXBlciBbQEFuZGVyczIwMTBdLiBUaGUgcGFyYW1ldGVyIHVzZWQgZm9yIHRoaXMgcHJvamVjdCBpcyBmaXRUeXBlPSJgciBmaXRUeXBlYCIuIFRoZW4sIERFU2VxMiBpbXBvc2VzIGEgQ294IFJlaWQtYWRqdXN0ZWQgcHJvZmlsZSBsaWtlbGlob29kIG1heGltaXphdGlvbiBbQGNveDE4OTcgYW5kIE1jQ2FydGh5LCAyMDEyXSBhbmQgdXNlcyB0aGUgbWF4aW11bSBfYSBwb3N0ZXJpb3JpXyAoTUFQKSBvZiB0aGUgZGlzcGVyc2lvbiBbV3UsIDIwMTNdLgoKPGNlbnRlcj4KIVtGaWd1cmUgODogRGlhZ25vc3RpYyBvZiB0aGUgZXN0aW1hdGlvbiBvZiB0aGUgc2l6ZSBmYWN0b3JzLl0oZmlndXJlcy9kaWFnU2l6ZUZhY3RvcnNIaXN0LnBuZykKCjwvY2VudGVyPgoKVGhlIGZpZ3VyZSA5IHNob3dzIHRoYXQgdGhlIHNjYWxpbmcgZmFjdG9ycyBvZiBERVNlcTIgYW5kIHRoZSB0b3RhbCBjb3VudCBub3JtYWxpemF0aW9uIGZhY3RvcnMgbWF5IG5vdCBwZXJmb3JtIHNpbWlsYXJseS4KCjxjZW50ZXI+CiFbRmlndXJlIDk6IFBsb3Qgb2YgdGhlIGVzdGltYXRlZCBzaXplIGZhY3RvcnMgYW5kIHRoZSB0b3RhbCBudW1iZXIgb2YgcmVhZHMgcGVyIHNhbXBsZS5dKGZpZ3VyZXMvZGlhZ1NpemVGYWN0b3JzVEMucG5nKXt3aWR0aD02MDB9Cgo8L2NlbnRlcj4KCkJveHBsb3RzIGFyZSBvZnRlbiB1c2VkIGFzIGEgcXVhbGl0YXRpdmUgbWVhc3VyZSBvZiB0aGUgcXVhbGl0eSBvZiB0aGUgbm9ybWFsaXphdGlvbiBwcm9jZXNzLCBhcyB0aGV5IHNob3cgaG93IGRpc3RyaWJ1dGlvbnMgYXJlIGdsb2JhbGx5IGFmZmVjdGVkIGR1cmluZyB0aGlzIHByb2Nlc3MuIFdlIGV4cGVjdCBub3JtYWxpemF0aW9uIHRvIHN0YWJpbGl6ZSBkaXN0cmlidXRpb25zIGFjcm9zcyBzYW1wbGVzLiBGaWd1cmUgMTAgc2hvd3MgYm94cGxvdHMgb2YgcmF3IChsZWZ0KSBhbmQgbm9ybWFsaXplZCAocmlnaHQpIGRhdGEgcmVzcGVjdGl2ZWx5LgoKPGNlbnRlcj4KIVtGaWd1cmUgMTA6IEJveHBsb3RzIG9mIHJhdyAobGVmdCkgYW5kIG5vcm1hbGl6ZWQgKHJpZ2h0KSByZWFkIGNvdW50cy5dKGZpZ3VyZXMvY291bnRzQm94cGxvdHMucG5nKXt3aWR0aD0xMjAwfQoKPC9jZW50ZXI+CgojIERpZmZlcmVudGlhbCBhbmFseXNpcwoKIyMgTW9kZWxpc2F0aW9uCgpERVNlcTIgYWltcyBhdCBmaXR0aW5nIG9uZSBsaW5lYXIgbW9kZWwgcGVyIGZlYXR1cmUuIEZvciB0aGlzIHByb2plY3QsIHRoZSBkZXNpZ24gdXNlZCBpcyBjb3VudHMgYHIgcGFzdGUoYXMuY2hhcmFjdGVyKGRlc2lnbihvdXQuREVTZXEyJGRkcykpLGNvbGxhcHNlPSIgIilgIGFuZCB0aGUgZ29hbCBpcyB0byBlc3RpbWF0ZSB0aGUgbW9kZWxzJyBjb2VmZmljaWVudHMgd2hpY2ggY2FuIGJlIGludGVycHJldGVkIGFzICRcbG9nXzIoXHRleHR0dHtGQ30pJC4gVGhlc2UgY29lZmZpY2llbnRzIHdpbGwgdGhlbiBiZSB0ZXN0ZWQgdG8gZ2V0IHAtdmFsdWVzIGFuZCBhZGp1c3RlZCBwLXZhbHVlcy4KCiMjIE91dGxpZXIgZGV0ZWN0aW9uCgpNb2RlbCBvdXRsaWVycyBhcmUgZmVhdHVyZXMgZm9yIHdoaWNoIGF0IGxlYXN0IG9uZSBzYW1wbGUgc2VlbXMgdW5yZWxhdGVkIHRvIHRoZSBleHBlcmltZW50YWwgb3Igc3R1ZHkgZGVzaWduLiBGb3IgZXZlcnkgZmVhdHVyZSBhbmQgZm9yIGV2ZXJ5IHNhbXBsZSwgdGhlIENvb2sncyBkaXN0YW5jZSBbQGNvb2sxOTc3XSByZWZsZWN0cyBob3cgdGhlIHNhbXBsZSBtYXRjaGVzIHRoZSBtb2RlbC4gQSBsYXJnZSB2YWx1ZSBvZiB0aGUgQ29vaydzIGRpc3RhbmNlIGluZGljYXRlcyBhbiBvdXRsaWVyIGNvdW50IGFuZCBwLXZhbHVlcyBhcmUgbm90IGNvbXB1dGVkIGZvciB0aGUgY29ycmVzcG9uZGluZyBmZWF0dXJlLiBgciBpZmVsc2UoIWNvb2tzQ3V0b2ZmLCJGb3IgdGhpcyBwcm9qZWN0LCB0aGUgZGV0ZWN0aW9uIG9mIG1vZGVsIG91dGxpZXJzIGhhdmUgYmVlbiB0dXJuZWQgb2ZmIGJ5IHNldHRpbmcgdGhlIGN1dC1vZmYgdG8gdGhlIGluZmluaXRlLiIsIiIpYAoKIyMgRGlzcGVyc2lvbnMgZXN0aW1hdGlvbgoKVGhlIERFU2VxMiBtb2RlbCBhc3N1bWVzIHRoYXQgdGhlIGNvdW50IGRhdGEgZm9sbG93IGEgbmVnYXRpdmUgYmlub21pYWwgZGlzdHJpYnV0aW9uIHdoaWNoIGlzIGEgcm9idXN0IGFsdGVybmF0aXZlIHRvIHRoZSBQb2lzc29uIGxhdyB3aGVuIGRhdGEgYXJlIG92ZXItZGlzcGVyc2VkICh0aGUgdmFyaWFuY2UgaXMgaGlnaGVyIHRoYW4gdGhlIG1lYW4pLiBUaGUgZmlyc3Qgc3RlcCBvZiB0aGUgc3RhdGlzdGljYWwgcHJvY2VkdXJlIGlzIHRvIGVzdGltYXRlIHRoZSBkaXNwZXJzaW9uIG9mIHRoZSBkYXRhLiBJdHMgcHVycG9zZSBpcyB0byBkZXRlcm1pbmUgdGhlIHNoYXBlIG9mIHRoZSBtZWFuLXZhcmlhbmNlIHJlbGF0aW9uc2hpcC4gVGhlIGRlZmF1bHQgaXMgdG8gYXBwbHkgYSBHTE0gKEdlbmVyYWxpemVkIExpbmVhciBNb2RlbCkgYmFzZWQgbWV0aG9kIChmaXRUeXBlPSJwYXJhbWV0cmljIiksIHdoaWNoIGNhbiBoYW5kbGUgY29tcGxleCBkZXNpZ25zIGJ1dCBtYXkgbm90IGNvbnZlcmdlIGluIHNvbWUgY2FzZXMuIFRoZSBhbHRlcm5hdGl2ZSBpcyB0byB1c2UgZml0VHlwZT0ibG9jYWwiIGFzIGRlc2NyaWJlZCBpbiB0aGUgb3JpZ2luYWwgcGFwZXIgW0BBbmRlcnMyMDEwXS4gVGhlIHBhcmFtZXRlciB1c2VkIGZvciB0aGlzIHByb2plY3QgaXMgZml0VHlwZT0gbG9jYWwuIFRoZW4sIERFU2VxMiBpbXBvc2VzIGEgQ294IFJlaWQtYWRqdXN0ZWQgcHJvZmlsZSBsaWtlbGlob29kIG1heGltaXphdGlvbiBbQGNveDE4OTcgYW5kIE1jQ2FydGh5LCAyMDEyXSBhbmQgdXNlcyB0aGUgbWF4aW11bSAgKE1BUCkgb2YgdGhlIGRpc3BlcnNpb24gW1d1LCAyMDEzXS4KCgo8Y2VudGVyPgohW0ZpZ3VyZSAxMTogRGlzcGVyc2lvbiBlc3RpbWF0ZXMgKGxlZnQpIGFuZCBkaWFnbm9zdGljIG9mIGxvZy1ub3JtYWxpdHkgKHJpZ2h0KS5dKGZpZ3VyZXMvZGlzcGVyc2lvbnNQbG90LnBuZyl7d2lkdGg9MTIwMH0KCjwvY2VudGVyPgoKVGhlIGxlZnQgcGFuZWwgb24gZmlndXJlIDExIHNob3dzIHRoZSByZXN1bHQgb2YgdGhlIGRpc3BlcnNpb24gZXN0aW1hdGlvbiBzdGVwLiBUaGUgeC0gYW5kIHktYXhlcyByZXByZXNlbnQgdGhlIG1lYW4gY291bnQgdmFsdWUgYW5kIHRoZSBlc3RpbWF0ZWQgZGlzcGVyc2lvbiByZXNwZWN0aXZlbHkuIEJsYWNrIGRvdHMgcmVwcmVzZW50IGVtcGlyaWNhbCBkaXNwZXJzaW9uIGVzdGltYXRlcyBmb3IgZWFjaCBmZWF0dXJlIChmcm9tIHRoZSBvYnNlcnZlZCBjb3VudHMpLiBUaGUgcmVkIGRvdHMgc2hvdyB0aGUgbWVhbi12YXJpYW5jZSByZWxhdGlvbnNoaXAgZnVuY3Rpb24gKGZpdHRlZCBkaXNwZXJzaW9uIHZhbHVlKSBhcyBlc3RpbWF0ZWQgYnkgdGhlIG1vZGVsLiBUaGUgYmx1ZSBkb3RzIGFyZSB0aGUgZmluYWwgZXN0aW1hdGVzIGZyb20gdGhlIG1heGltdW0gX2EgcG9zdGVyaW9yaV8gYW5kIGFyZSB1c2VkIHRvIHBlcmZvcm0gdGhlIHN0YXRpc3RpY2FsIHRlc3QuIEJsdWUgY2lyY2xlcyAoaWYgYW55KSBwb2ludCBvdXQgZGlzcGVyc2lvbiBvdXRsaWVycy4gVGhlc2UgYXJlIGZlYXR1cmVzIHdpdGggYSB2ZXJ5IGhpZ2ggZW1waXJpY2FsIHZhcmlhbmNlIChjb21wdXRlZCBmcm9tIG9ic2VydmVkIGNvdW50cykuIFRoZXNlIGhpZ2ggZGlzcGVyc2lvbiB2YWx1ZXMgZmFsbCBmYXIgZnJvbSB0aGUgbW9kZWwgZXN0aW1hdGlvbi4gRm9yIHRoZXNlIGZlYXR1cmVzLCB0aGUgc3RhdGlzdGljYWwgdGVzdCBpcyBiYXNlZCBvbiB0aGUgZW1waXJpY2FsIHZhcmlhbmNlIGluIG9yZGVyIHRvIGJlIG1vcmUgY29uc2VydmF0aXZlIHRoYW4gd2l0aCB0aGUgTUFQIGRpc3BlcnNpb24uIFRoZXNlIGZlYXR1cmVzIHdpbGwgaGF2ZSBsb3cgY2hhbmNlIHRvIGJlIGRlY2xhcmVkIHNpZ25pZmljYW50LiBUaGUgZmlndXJlIG9uIHRoZSByaWdodCBwYW5lbCBhbGxvd3MgdG8gY2hlY2sgdGhlIGh5cG90aGVzaXMgb2YgbG9nLW5vcm1hbGl0eSBvZiB0aGUgZGlzcGVyc2lvbnMuCgojIyBTdGF0aXN0aWNhbCB0ZXN0IGZvciBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbgoKT25jZSB0aGUgZGlzcGVyc2lvbiBlc3RpbWF0aW9uIGFuZCB0aGUgbW9kZWwgZml0dGluZyBoYXZlIGJlZW4gZG9uZSwgREVTZXEyIGNhbiBwZXJmb3JtIHRoZSBzdGF0aXN0aWNhbCB0ZXN0aW5nLiBGaWd1cmUgMTIgc2hvd3MgdGhlIGRpc3RyaWJ1dGlvbnMgb2YgcmF3IHAtdmFsdWVzIGNvbXB1dGVkIGJ5IHRoZSBzdGF0aXN0aWNhbCB0ZXN0IGZvciB0aGUgY29tcGFyaXNvbihzKSBkb25lLiBUaGlzIGRpc3RyaWJ1dGlvbiBpcyBleHBlY3RlZCB0byBiZSBhIG1peHR1cmUgb2YgYSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBvbiAkWzAsMV0kIGFuZCBhIHBlYWsgYXJvdW5kIDAgY29ycmVzcG9uZGluZyB0byB0aGUgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGZlYXR1cmVzLgoKCjxjZW50ZXI+CiFbRmlndXJlIDEyOiBEaXN0cmlidXRpb24ocykgb2YgcmF3IHAtdmFsdWVzLl0oZmlndXJlcy9yYXdwSGlzdC5wbmcpCgo8L2NlbnRlcj4KCgojIyBJbmRlcGVuZGVudCBmaWx0ZXJpbmcKCkRFU2VxMiBjYW4gcGVyZm9ybSBhbiBpbmRlcGVuZGVudCBmaWx0ZXJpbmcgdG8gaW5jcmVhc2UgdGhlIGRldGVjdGlvbiBwb3dlciBvZiBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZmVhdHVyZXMgYXQgdGhlIHNhbWUgZXhwZXJpbWVudC13aWRlIHR5cGUgSSBlcnJvci4gU2luY2UgZmVhdHVyZXMgd2l0aCB2ZXJ5IGxvdyBjb3VudHMgYXJlIG5vdCBsaWtlbHkgdG8gc2VlIHNpZ25pZmljYW50IGRpZmZlcmVuY2VzIHR5cGljYWxseSBkdWUgdG8gaGlnaCBkaXNwZXJzaW9uLCBpdCBkZWZpbmVzIGEgdGhyZXNob2xkIG9uIHRoZSBtZWFuIG9mIHRoZSBub3JtYWxpemVkIGNvdW50cyBpcnJlc3BlY3RpdmUgb2YgdGhlIGJpb2xvZ2ljYWwgY29uZGl0aW9uLiBUaGlzIHByb2NlZHVyZSBpcyBpbmRlcGVuZGVudCBiZWNhdXNlIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgdmFyaWFibGVzIGluIHRoZSBkZXNpZ24gZm9ybXVsYSBpcyBub3QgdXNlZCBbQExvdmUyMDE0XS4KCmBgYHtyICwgZWNobz1GQUxTRSwgZXZhbCA9IEYscmVzdWx0cz0iYXNpcyJ9CmlmIChpbmRlcGVuZGVudEZpbHRlcmluZyl7CiAgY2F0KCJUYWJsZSA2IHJlcG9ydHMgdGhlIHRocmVzaG9sZHMgdXNlZCBmb3IgZWFjaCBjb21wYXJpc29uIGFuZCB0aGUgbnVtYmVyIG9mIGZlYXR1cmVzIGRpc2NhcmRlZCBieSB0aGUgaW5kZXBlbmRlbnQgZmlsdGVyaW5nLiBBZGp1c3RlZCBwLXZhbHVlcyBvZiBkaXNjYXJkZWQgZmVhdHVyZXMgYXJlIHRoZW4gc2V0IHRvIE5BLlxuIikKICBwcmludCh4dGFibGUoc3VtbWFyeVJlc3VsdHMkdGFiSW5kZXBGaWx0ZXJpbmcsY2FwdGlvbj0iVGFibGUgNjogTnVtYmVyIG9mIGZlYXR1cmVzIGRpc2NhcmRlZCBieSB0aGUgaW5kZXBlbmRlbnQgZmlsdGVyaW5nIGZvciBlYWNoIGNvbXBhcmlzb24uIiksdHlwZT0iaHRtbCIsaW5jbHVkZS5yb3duYW1lcz1GQUxTRSwgaHRtbC50YWJsZS5hdHRyaWJ1dGVzID0gImFsaWduPSdjZW50ZXInIikKfSBlbHNlewogIGNhdCgiRm9yIHRoaXMgcHJvamVjdCwgbm8gaW5kZXBlbmRlbnQgZmlsdGVyaW5nIGhhcyBiZWVuIHBlcmZvcm1lZC4iKQp9CmBgYAoKIyMgRmluYWwgcmVzdWx0cwoKQSBwLXZhbHVlIGFkanVzdG1lbnQgaXMgcGVyZm9ybWVkIHRvIHRha2UgaW50byBhY2NvdW50IG11bHRpcGxlIHRlc3RpbmcgYW5kIGNvbnRyb2wgdGhlIGZhbHNlIHBvc2l0aXZlIHJhdGUgdG8gYSBjaG9zZW4gbGV2ZWwgJFxhbHBoYSQuIEZvciB0aGlzIGFuYWx5c2lzLCBhIGByIHBBZGp1c3RNZXRob2RgIHAtdmFsdWUgYWRqdXN0bWVudCB3YXMgcGVyZm9ybWVkIFtAQkgxOTk1IGFuZCBCWTIwMDFdIGFuZCB0aGUgbGV2ZWwgb2YgY29udHJvbGxlZCBmYWxzZSBwb3NpdGl2ZSByYXRlIHdhcyBzZXQgdG8gYHIgYWxwaGFgLgoKYGBge3IgLCBlY2hvPUZBTFNFLCBldmFsID0gRixyZXN1bHRzPSJhc2lzIn0KcHJpbnQoeHRhYmxlKHN1bW1hcnlSZXN1bHRzJG5EaWZmVG90YWwsY2FwdGlvbj1wYXN0ZTAoaWZlbHNlKGluZGVwZW5kZW50RmlsdGVyaW5nLCJUYWJsZSA3OiAiLCJUYWJsZSA2OiAiKSwiTnVtYmVyIG9mIHVwLSwgZG93bi0gYW5kIHRvdGFsIG51bWJlciBvZiBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZmVhdHVyZXMgZm9yIGVhY2ggY29tcGFyaXNvbi4iKSksdHlwZT0iaHRtbCIsaW5jbHVkZS5yb3duYW1lcz1GQUxTRSwgaHRtbC50YWJsZS5hdHRyaWJ1dGVzID0gImFsaWduPSdjZW50ZXInIikKYGBgCgpGaWd1cmUgMTMgYXJlIHRoZSBmaXRuZXNzIGRlZmVjdHMgKCRcbG9nXzIkIHJhdGlvcykgcGxvdHRlZCBhcyBhIGZ1bmN0aW9uIG9mIG1lYW4gY291bnRzIC0tIAp0aGlzIGlzIHVzZWZ1bCBmb3Iga25vd2luZyB3aGV0aGVyIHNpZ25pZmljYW50IGFyZSBjb21pbmcgZnJvbSB1bnVzdWFsIGxvdyAobm9pc3kpIGNvdW50cwoKCjxjZW50ZXI+CiFbRmlndXJlIDEzOiBMb2cgUmF0aW8gdnMuIG1lYW4gQ1BNIG9mIGVhY2ggY29tcGFyaXNvbi5dKGZpZ3VyZXMvTUFQbG90LnBuZykKCjwvY2VudGVyPgoKCkZpZ3VyZSAxNCBzaG93cyB0aGUgdm9sY2FubyBwbG90cyBmb3IgdGhlIGNvbXBhcmlzb25zIHBlcmZvcm1lZCBhbmQgZGlmZmVyZW50aWFsbHkgZXhwcmVzc2VkIGZlYXR1cmVzIGFyZSBzdGlsbCBoaWdobGlnaHRlZCBpbiByZWQuIEEgdm9sY2FubyBwbG90IHJlcHJlc2VudHMgdGhlIGxvZyBvZiB0aGUgYWRqdXN0ZWQgUCB2YWx1ZSBhcyBhIGZ1bmN0aW9uIG9mIHRoZSBsb2cgcmF0aW8gb2YgZGlmZmVyZW50aWFsIGV4cHJlc3Npb24uCgoKPGNlbnRlcj4KCiFbRmlndXJlIDE0OiBWb2xjYW5vIHBsb3Qocykgb2YgZWFjaCBjb21wYXJpc29uLiBSZWQgZG90cyByZXByZXNlbnQgc2lnbmlmaWNhbnRseSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZmVhdHVyZXMuXShmaWd1cmVzL3ZvbGNhbm9QbG90LnBuZykKCjwvY2VudGVyPgoKCgo8Y2VudGVyPgoKIVtGaWd1cmUgMTU6IEZpdG5lc3MgZGVmZWN0IHBsb3RzLl0oZmlndXJlcy9GRFBsb3RzLnBuZykKPC9jZW50ZXI+CgpGdWxsIHJlc3VsdHMgYXMgd2VsbCBhcyBsaXN0cyBvZiBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZmVhdHVyZXMgYXJlIHByb3ZpZGVkIGluIHRoZSBmb2xsb3dpbmcgdGV4dCBmaWxlcyB3aGljaCBjYW4gYmUgZWFzaWx5IHJlYWQgaW4gYSBzcHJlYWRzaGVldC4gRm9yIGVhY2ggY29tcGFyaXNvbjoKCi0gVGVzdFZzUmVmLmNvbXBsZXRlLnR4dCBjb250YWlucyByZXN1bHRzIGZvciBhbGwgdGhlIGZlYXR1cmVzOwotIFRlc3RWc1JlZi51cC50eHQgY29udGFpbnMgcmVzdWx0cyBmb3Igc2lnbmlmaWNhbnRseSB1cC1yZWd1bGF0ZWQgZmVhdHVyZXMuIEZlYXR1cmVzIGFyZSBvcmRlcmVkIGZyb20gdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYWRqdXN0ZWQgcC12YWx1ZSB0byB0aGUgbGVzcyBzaWduaWZpY2FudCBvbmU7Ci0gVGVzdFZzUmVmLmRvd24udHh0IGNvbnRhaW5zIHJlc3VsdHMgZm9yIHNpZ25pZmljYW50bHkgZG93bi1yZWd1bGF0ZWQgZmVhdHVyZXMuIEZlYXR1cmVzIGFyZSBvcmRlcmVkIGZyb20gdGhlIG1vc3Qgc2lnbmlmaWNhbnQgYWRqdXN0ZWQgcC12YWx1ZSB0byB0aGUgbGVzcyBzaWduaWZpY2FudCBvbmUuCgpUaGVzZSBmaWxlcyBjb250YWluIHRoZSBmb2xsb3dpbmcgY29sdW1uczoKCi0gSWQ6IHVuaXF1ZSBmZWF0dXJlIGlkZW50aWZpZXI7Ci0gc2FtcGxlTmFtZTogcmF3IGNvdW50cyBwZXIgc2FtcGxlOwotIG5vcm0uc2FtcGxlTmFtZTogcm91bmRlZCBub3JtYWxpemVkIGNvdW50cyBwZXIgc2FtcGxlOwotIGJhc2VNZWFuOiBiYXNlIG1lYW4gb3ZlciBhbGwgc2FtcGxlczsKLSBgciBwYXN0ZShwYXN0ZShsZXZlbHModGFyZ2V0Wyx2YXJJbnRdKVstbmxldmVscyh0YXJnZXRbLHZhckludF0pXSxjb2xsYXBzZT0iLCAiKSxsZXZlbHModGFyZ2V0Wyx2YXJJbnRdKVtubGV2ZWxzKHRhcmdldFssdmFySW50XSldLHNlcD0iIGFuZCAiKWA6IG1lYW5zIChyb3VuZGVkKSBvZiBub3JtYWxpemVkIGNvdW50cyBvZiB0aGUgYmlvbG9naWNhbCBjb25kaXRpb25zOwotIEZvbGRDaGFuZ2U6IGZvbGQgY2hhbmdlIG9mIGV4cHJlc3Npb24sIGNhbGN1bGF0ZWQgYXMgJDJee1xsb2dfMihcdGV4dHtGQ30pfSQ7Ci0gbG9nMkZvbGRDaGFuZ2U6ICRcbG9nXzIoXHRleHR7RkN9KSQgYXMgZXN0aW1hdGVkIGJ5IHRoZSBHTE0gbW9kZWwuIEl0IHJlZmxlY3RzIHRoZSBkaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBiZXR3ZWVuIFRlc3QgYW5kIFJlZiBhbmQgY2FuIGJlIGludGVycHJldGVkIGFzICRcbG9nXzIoXGZyYWN7XHRleHR7VGVzdH19e1x0ZXh0e1JlZn19KSQuIElmIHRoaXMgdmFsdWUgaXM6CiAgICArIGFyb3VuZCAwOiB0aGUgZmVhdHVyZSBleHByZXNzaW9uIGlzIHNpbWlsYXIgaW4gYm90aCBjb25kaXRpb25zOwogICAgKyBwb3NpdGl2ZTogdGhlIGZlYXR1cmUgaXMgdXAtcmVndWxhdGVkICgkXHRleHR7VGVzdH0gPiBcdGV4dHtSZWZ9JCk7CiAgICArIG5lZ2F0aXZlOiB0aGUgZmVhdHVyZSBpcyBkb3duLXJlZ3VsYXRlZCAoJFx0ZXh0e1Rlc3R9IDwgXHRleHR7UmVmfSQpOwotIHB2YWx1ZTogcmF3IHAtdmFsdWUgZnJvbSB0aGUgc3RhdGlzdGljYWwgdGVzdDsKLSBwYWRqOiBhZGp1c3RlZCBwLXZhbHVlIG9uIHdoaWNoIHRoZSBjdXQtb2ZmICRcYWxwaGEkIGlzIGFwcGxpZWQ7Ci0gZGlzcEdlbmVFc3Q6IGRpc3BlcnNpb24gcGFyYW1ldGVyIGVzdGltYXRlZCBmcm9tIGZlYXR1cmUgY291bnRzIChpLmUuIGJsYWNrIGRvdHMgb24gZmlndXJlIDExKTsKLSBkaXNwRml0OiBkaXNwZXJzaW9uIHBhcmFtZXRlciBlc3RpbWF0ZWQgZnJvbSB0aGUgbW9kZWwgKGkuZS4gcmVkIGRvdHMgb24gZmlndXJlIDExKTsKLSBkaXNwTUFQOiBkaXNwZXJzaW9uIHBhcmFtZXRlciBlc3RpbWF0ZWQgZnJvbSB0aGUgTWF4aW11bSBfQSBQb3N0ZXJpb3JpXyBtb2RlbDsKLSBkaXNwZXJzaW9uOiBmaW5hbCBkaXNwZXJzaW9uIHBhcmFtZXRlciB1c2VkIHRvIHBlcmZvcm0gdGhlIHRlc3QgKGkuZS4gYmx1ZSBkb3RzIGFuZCBjaXJjbGVzIG9uIGZpZ3VyZSAxMSk7Ci0gYmV0YUNvbnY6IGNvbnZlcmdlbmNlIG9mIHRoZSBjb2VmZmljaWVudHMgb2YgdGhlIG1vZGVsIChUUlVFIG9yIEZBTFNFKTsKLSBtYXhDb29rczogbWF4aW11bSBDb29rJ3MgZGlzdGFuY2Ugb2YgdGhlIGZlYXR1cmUuCgojIFIgc2Vzc2lvbiBpbmZvcm1hdGlvbiBhbmQgcGFyYW1ldGVycwoKVGhlIHZlcnNpb25zIG9mIHRoZSBSIHNvZnR3YXJlIGFuZCBCaW9jb25kdWN0b3IgcGFja2FnZXMgdXNlZCBmb3IgdGhpcyBhbmFseXNpcyBhcmUgbGlzdGVkIGJlbG93LiBJdCBpcyBpbXBvcnRhbnQgdG8gc2F2ZSB0aGVtIGlmIG9uZSB3YW50cyB0byByZS1wZXJmb3JtIHRoZSBhbmFseXNpcyBpbiB0aGUgc2FtZSBjb25kaXRpb25zLgoKYGBge3IgLCBlY2hvPUZBTFNFLCByZXN1bHRzPSJhc2lzIn0Kc2kgPC0gYXMuY2hhcmFjdGVyKHRvTGF0ZXgoc2Vzc2lvbkluZm8oKSkpCnNpIDwtIHNpWy1jKDEsbGVuZ3RoKHNpKSldCnNpIDwtIGdzdWIoIihcXFxcdmVyYil8KFxcfCkiLCAiIiwgc2kpCnNpIDwtIGdzdWIoIn4iLCAiICIsIHNpKQpzaSA8LSBwYXN0ZShzaSwgY29sbGFwc2U9IiAiKQpzaSA8LSB1bmxpc3Qoc3Ryc3BsaXQoc2ksICJcXFxcaXRlbSIpKQpjYXQocGFzdGUoc2ksIGNvbGxhcHNlPSJcbiAtIiksICJcbiIpCmBgYAoKUGFyYW1ldGVyIHZhbHVlcyB1c2VkIGZvciB0aGlzIGFuYWx5c2lzIGFyZToKCi0gd29ya0RpcjogYHIgd29ya0RpcmAKLSBwcm9qZWN0TmFtZTogYHIgcHJvamVjdE5hbWVgCi0gYXV0aG9yOiBgciBhdXRob3JgCi0gdGFyZ2V0RmlsZTogYHIgdGFyZ2V0RmlsZWAKLSByYXdEaXI6IGByIHJhd0RpcmAKLSBmZWF0dXJlc1RvUmVtb3ZlOiBgciBpZmVsc2UoaXMubnVsbChmZWF0dXJlc1RvUmVtb3ZlKSwiTlVMTCIscGFzdGUoZmVhdHVyZXNUb1JlbW92ZSxjb2xsYXBzZT0iLCAiKSlgCi0gdmFySW50OiBgciB2YXJJbnRgCi0gY29uZFJlZjogYHIgY29uZFJlZmAKLSBiYXRjaDogYHIgaWZlbHNlKGlzLm51bGwoYmF0Y2gpLCJOVUxMIixiYXRjaClgCi0gZml0VHlwZTogYHIgZml0VHlwZWAKLSBjb29rc0N1dG9mZjogYHIgY29va3NDdXRvZmZgCi0gaW5kZXBlbmRlbnRGaWx0ZXJpbmc6IGByIGluZGVwZW5kZW50RmlsdGVyaW5nYAotIGFscGhhOiBgciBhbHBoYWAKLSBwQWRqdXN0TWV0aG9kOiBgciBwQWRqdXN0TWV0aG9kYAotIHR5cGVUcmFuczogYHIgdHlwZVRyYW5zYAotIGxvY2Z1bmM6IGByIGxvY2Z1bmNgCi0gY29sb3JzOiBgciBjb2xvcnNgCgojIEJpYmxpb2dyYXBoeQo=